﻿Imports System.Runtime.InteropServices

Namespace Global.Runa.UI.Threading

    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure PriorityRange

        Public Shared ReadOnly All As PriorityRange
        Public Shared ReadOnly None As PriorityRange

        Private _min As DispatcherPriority
        Private _isMinInclusive As Boolean
        Private _max As DispatcherPriority
        Private _isMaxInclusive As Boolean

        Shared Sub New()
            PriorityRange.All = New PriorityRange(DispatcherPriority.Inactive, DispatcherPriority.Send, True)
            PriorityRange.None = New PriorityRange(DispatcherPriority.Invalid, DispatcherPriority.Invalid, True)
        End Sub

        Private Sub New(ByVal min As DispatcherPriority, ByVal max As DispatcherPriority, ByVal ignored As Boolean)
            Me._min = min
            Me._isMinInclusive = True
            Me._max = max
            Me._isMaxInclusive = True
        End Sub

        Public Sub New(ByVal min As DispatcherPriority, ByVal max As DispatcherPriority)
            Me.Initialize(min, True, max, True)
        End Sub

        Public Sub New(ByVal min As DispatcherPriority, ByVal isMinInclusive As Boolean, ByVal max As DispatcherPriority, ByVal isMaxInclusive As Boolean)        
            Me.Initialize(min, isMinInclusive, max, isMaxInclusive)
        End Sub

        Public ReadOnly Property Min As DispatcherPriority
            Get
                Return Me._min
            End Get
        End Property

        Public ReadOnly Property Max As DispatcherPriority
            Get
                Return Me._max
            End Get
        End Property

        Public ReadOnly Property IsMinInclusive As Boolean
            Get
                Return Me._isMinInclusive
            End Get
        End Property

        Public ReadOnly Property IsMaxInclusive As Boolean
            Get
                Return Me._isMaxInclusive
            End Get
        End Property

        Public ReadOnly Property IsValid As Boolean
            Get
                Return ((((Me._min > DispatcherPriority.Invalid) AndAlso (Me._min <= DispatcherPriority.Send)) AndAlso (Me._max > DispatcherPriority.Invalid)) AndAlso (Me._max <= DispatcherPriority.Send))
            End Get
        End Property

        Public Function Contains(ByVal priority As DispatcherPriority) As Boolean
            If ((priority <= DispatcherPriority.Invalid) OrElse (priority > DispatcherPriority.Send)) Then
                Return False
            End If
            If Not Me.IsValid Then
                Return False
            End If
            Dim flag As Boolean = False
            If Me._isMinInclusive Then
                flag = (priority >= Me._min)
            Else
                flag = (priority > Me._min)
            End If
            If Not flag Then
                Return flag
            End If
            If Me._isMaxInclusive Then
                Return (priority <= Me._max)
            End If
            Return (priority < Me._max)
        End Function

        Public Function Contains(ByVal priorityRange As PriorityRange) As Boolean
            If Not priorityRange.IsValid Then
                Return False
            End If
            If Not Me.IsValid Then
                Return False
            End If
            Dim flag As Boolean = False
            If priorityRange._isMinInclusive Then
                flag = Me.Contains(priorityRange.Min)
            ElseIf ((priorityRange.Min >= Me._min) AndAlso (priorityRange.Min < Me._max)) Then
                flag = True
            End If
            If flag Then
                If priorityRange._isMaxInclusive Then
                    Return Me.Contains(priorityRange.Max)
                End If
                If ((priorityRange.Max > Me._min) AndAlso (priorityRange.Max <= Me._max)) Then
                    flag = True
                End If
            End If
            Return flag
        End Function

        Public Overrides Function Equals(ByVal o As Object) As Boolean
            Return (TypeOf o Is PriorityRange AndAlso Me.Equals(DirectCast(o, PriorityRange)))
        End Function

        Public Overloads Function Equals(ByVal priorityRange As PriorityRange) As Boolean
            Return ((((priorityRange._min = Me._min) AndAlso (priorityRange._isMinInclusive = Me._isMinInclusive)) AndAlso (priorityRange._max = Me._max)) AndAlso (priorityRange._isMaxInclusive = Me._isMaxInclusive))
        End Function

        Public Shared Operator =(ByVal priorityRange1 As PriorityRange, ByVal priorityRange2 As PriorityRange) As Boolean
            Return priorityRange1.Equals(priorityRange2)
        End Operator

        Public Shared Operator <>(ByVal priorityRange1 As PriorityRange, ByVal priorityRange2 As PriorityRange) As Boolean
            Return Not (priorityRange1 = priorityRange2)
        End Operator

        Private Sub Initialize(ByVal min As DispatcherPriority, ByVal isMinInclusive As Boolean, ByVal max As DispatcherPriority, ByVal isMaxInclusive As Boolean)
            If ((min < DispatcherPriority.Invalid) OrElse (min > DispatcherPriority.Send)) Then
#If WINDOWS_PHONE Or NETFX_CORE Then
                Throw New ArgumentException("min")
#Else
                Throw New InvalidEnumArgumentException("min", CInt(min), GetType(DispatcherPriority))
#End If
            End If
            If (min = DispatcherPriority.Inactive) Then
                Throw New ArgumentException("InvalidPriority", "min")
            End If
            If ((max < DispatcherPriority.Invalid) OrElse (max > DispatcherPriority.Send)) Then
#If WINDOWS_PHONE Or NETFX_CORE Then
                Throw New ArgumentException("max")
#Else
                Throw New InvalidEnumArgumentException("max", CInt(max), GetType(DispatcherPriority))
#End If
            End If
            If (max = DispatcherPriority.Inactive) Then
                Throw New ArgumentException("InvalidPriority", "max")
            End If
            If (max < min) Then
                Throw New ArgumentException("InvalidPriorityRangeOrder")
            End If
            Me._min = min
            Me._isMinInclusive = isMinInclusive
            Me._max = max
            Me._isMaxInclusive = isMaxInclusive
        End Sub

    End Structure

End Namespace